```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring Boot 初始化方法指南 | 技术小馆</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #1a1a1a;
            line-height: 1.6;
        }
        .heading-font {
            font-family: 'Noto Serif SC', serif;
        }
        .code-block {
            background-color: #f8f8f8;
            border-left: 4px solid #4299e1;
            font-family: Monaco, Consolas, "Courier New", monospace;
        }
        .hover-grow {
            transition: transform 0.2s ease;
        }
        .hover-grow:hover {
            transform: translateY(-2px);
        }
        .method-card {
            border-radius: 12px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
            transition: all 0.3s ease;
        }
        .method-card:hover {
            box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
            border-color: #4299e1;
        }
        .highlight-box {
            position: relative;
        }
        .highlight-box::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 4px;
            height: 100%;
            background: linear-gradient(to bottom, #4299e1, #38b2ac);
            border-radius: 4px 0 0 4px;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <header class="relative bg-gradient-to-r from-blue-800 to-blue-600 text-white py-20 px-4 md:px-8 overflow-hidden">
        <div class="absolute inset-0 opacity-20">
            <div class="absolute inset-0 bg-gradient-to-br from-blue-900 via-transparent to-blue-900"></div>
        </div>
        <div class="container mx-auto relative z-10">
            <div class="max-w-3xl mx-auto text-center">
                <div class="inline-block px-4 py-2 bg-blue-700 bg-opacity-50 rounded-full mb-6">
                    <span class="text-sm font-medium">Spring Boot 开发指南</span>
                </div>
                <h1 class="heading-font text-4xl md:text-5xl font-bold mb-6 leading-tight">Spring Boot 项目启动初始化方法</h1>
                <p class="text-xl text-blue-100 max-w-2xl mx-auto">探索多种优雅方式在应用启动时执行初始化逻辑，构建更健壮的Spring Boot应用</p>
                <div class="mt-10 flex justify-center">
                    <a href="#content" class="flex items-center px-6 py-3 bg-white text-blue-700 font-medium rounded-full hover:bg-opacity-90 transition-all duration-300 hover:shadow-lg">
                        <span>开始探索</span>
                        <i class="fas fa-arrow-down ml-2"></i>
                    </a>
                </div>
            </div>
        </div>
    </header>

    <!-- Content Section -->
    <main id="content" class="container mx-auto px-4 md:px-8 py-16 max-w-5xl">
        <div class="prose prose-lg max-w-none">
            <div class="mb-16">
                <p class="text-xl text-gray-700 leading-relaxed">
                    在Spring Boot项目启动成功后，可以通过编写自定义的初始化方法或使用Spring Boot提供的特定注解来执行一些初始化操作。这些方法可以帮助您完成诸如数据库初始化、缓存预热、配置加载等关键任务。
                </p>
            </div>

            <!-- Methods Grid -->
            <div class="grid md:grid-cols-2 gap-8 mb-16">
                <!-- Method 1 -->
                <div class="method-card bg-white p-6 border border-gray-200 hover-grow">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 rounded-full bg-blue-100 flex items-center justify-center mr-4">
                            <i class="fas fa-magic text-blue-600 text-xl"></i>
                        </div>
                        <h3 class="heading-font text-2xl font-semibold">@PostConstruct 注解</h3>
                    </div>
                    <p class="text-gray-600 mb-4">在需要进行初始化操作的方法上添加<code class="bg-blue-50 text-blue-700 px-2 py-1 rounded">@PostConstruct</code>注解。该注解会在Spring容器初始化Bean之后，自动调用被注解的方法。</p>
                    <div class="highlight-box bg-gray-50 p-4 rounded-lg mb-4">
                        <p class="text-gray-700 font-medium">核心特点：</p>
                        <ul class="list-disc pl-5 text-gray-600">
                            <li>简单直接，只需添加一个注解</li>
                            <li>方法将在Bean初始化完成后立即执行</li>
                            <li>适用于类内部的初始化逻辑</li>
                        </ul>
                    </div>
                </div>

                <!-- Method 2 -->
                <div class="method-card bg-white p-6 border border-gray-200 hover-grow">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 rounded-full bg-green-100 flex items-center justify-center mr-4">
                            <i class="fas fa-rocket text-green-600 text-xl"></i>
                        </div>
                        <h3 class="heading-font text-2xl font-semibold">ApplicationRunner 接口</h3>
                    </div>
                    <p class="text-gray-600 mb-4">实现<code class="bg-green-50 text-green-700 px-2 py-1 rounded">ApplicationRunner</code>接口的<code class="bg-green-50 text-green-700 px-2 py-1 rounded">run</code>方法，该方法在应用启动后会被自动调用。</p>
                    <div class="highlight-box bg-gray-50 p-4 rounded-lg mb-4">
                        <p class="text-gray-700 font-medium">核心特点：</p>
                        <ul class="list-disc pl-5 text-gray-600">
                            <li>可以访问应用启动参数</li>
                            <li>执行时机稍晚于CommandLineRunner</li>
                            <li>适合需要访问完整应用上下文的场景</li>
                        </ul>
                    </div>
                </div>

                <!-- Method 3 -->
                <div class="method-card bg-white p-6 border border-gray-200 hover-grow">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 rounded-full bg-purple-100 flex items-center justify-center mr-4">
                            <i class="fas fa-terminal text-purple-600 text-xl"></i>
                        </div>
                        <h3 class="heading-font text-2xl font-semibold">CommandLineRunner 接口</h3>
                    </div>
                    <p class="text-gray-600 mb-4">实现<code class="bg-purple-50 text-purple-700 px-2 py-1 rounded">CommandLineRunner</code>接口的<code class="bg-purple-50 text-purple-700 px-2 py-1 rounded">run</code>方法，Spring Boot会在启动成功后自动调用它。</p>
                    <div class="highlight-box bg-gray-50 p-4 rounded-lg mb-4">
                        <p class="text-gray-700 font-medium">核心特点：</p>
                        <ul class="list-disc pl-5 text-gray-600">
                            <li>可以访问原始命令行参数</li>
                            <li>执行时机早于ApplicationRunner</li>
                            <li>适合简单的启动任务</li>
                        </ul>
                    </div>
                </div>

                <!-- Method 4 -->
                <div class="method-card bg-white p-6 border border-gray-200 hover-grow">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 rounded-full bg-yellow-100 flex items-center justify-center mr-4">
                            <i class="fas fa-bell text-yellow-600 text-xl"></i>
                        </div>
                        <h3 class="heading-font text-2xl font-semibold">ApplicationListener 接口</h3>
                    </div>
                    <p class="text-gray-600 mb-4">监听<code class="bg-yellow-50 text-yellow-700 px-2 py-1 rounded">ContextRefreshedEvent</code>事件，当Spring容器刷新完成后触发。</p>
                    <div class="highlight-box bg-gray-50 p-4 rounded-lg mb-4">
                        <p class="text-gray-700 font-medium">核心特点：</p>
                        <ul class="list-disc pl-5 text-gray-600">
                            <li>基于事件驱动机制</li>
                            <li>可以监听多种应用事件</li>
                            <li>适合需要精确控制执行时机的场景</li>
                        </ul>
                    </div>
                </div>
            </div>

            <!-- Detailed Content -->
            <div class="space-y-16">
                <!-- PostConstruct Section -->
                <section>
                    <div class="flex items-center mb-6">
                        <h2 id="postconstruct" class="heading-font text-3xl font-bold text-gray-800">@PostConstruct 注解</h2>
                        <span class="ml-4 px-3 py-1 bg-blue-100 text-blue-800 text-sm font-medium rounded-full">推荐</span>
                    </div>
                    <div class="pl-2 border-l-4 border-blue-500 mb-6">
                        <p class="text-lg text-gray-700">通过<code class="bg-blue-50 text-blue-700 px-2 py-1 rounded">@PostConstruct</code>注解标记的方法将会在Spring容器启动时自动调用，执行其中的初始化逻辑。</p>
                    </div>
                    <div class="code-block p-4 rounded-lg mb-6 overflow-x-auto">
                        <pre class="text-sm"><code>import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;

@Component
public class DataInitializer {
    
    @PostConstruct
    public void init() {
        // 在此处编写初始化逻辑
        System.out.println("使用@PostConstruct执行初始化...");
    }
}</code></pre>
                    </div>
                    <div class="bg-blue-50 border border-blue-100 rounded-lg p-4">
                        <h4 class="font-semibold text-blue-800 mb-2 flex items-center">
                            <i class="fas fa-lightbulb mr-2"></i>
                            最佳实践建议
                        </h4>
                        <ul class="text-blue-700 space-y-2">
                            <li class="flex items-start">
                                <i class="fas fa-check-circle mt-1 mr-2 text-blue-500"></i>
                                <span>适用于Bean内部的简单初始化逻辑</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle mt-1 mr-2 text-blue-500"></i>
                                <span>避免在此方法中执行耗时操作，以免延迟应用启动</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle mt-1 mr-2 text-blue-500"></i>
                                <span>适合数据预加载、缓存初始化等任务</span>
                            </li>
                        </ul>
                    </div>
                </section>

                <!-- ApplicationRunner Section -->
                <section>
                    <h2 id="applicationrunner" class="heading-font text-3xl font-bold text-gray-800 mb-6">ApplicationRunner 接口</h2>
                    <div class="pl-2 border-l-4 border-green-500 mb-6">
                        <p class="text-lg text-gray-700">通过实现<code class="bg-green-50 text-green-700 px-2 py-1 rounded">ApplicationRunner</code>接口，可以在<code class="bg-green-50 text-green-700 px-2 py-1 rounded">run</code>方法中编写初始化操作的逻辑。</p>
                    </div>
                    <div class="code-block p-4 rounded-lg mb-6 overflow-x-auto">
                        <pre class="text-sm"><code>import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class MyInitializer implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 在应用启动后执行初始化操作
        // 可以访问ApplicationArguments获取启动参数
        System.out.println("使用ApplicationRunner执行初始化...");
    }
}</code></pre>
                    </div>
                    <div class="grid md:grid-cols-2 gap-6">
                        <div class="bg-green-50 border border-green-100 rounded-lg p-4">
                            <h4 class="font-semibold text-green-800 mb-2">优点</h4>
                            <ul class="text-green-700 space-y-2">
                                <li>可以访问应用启动参数</li>
                                <li>执行时机在CommandLineRunner之后</li>
                                <li>支持更复杂的参数处理</li>
                            </ul>
                        </div>
                        <div class="bg-orange-50 border border-orange-100 rounded-lg p-4">
                            <h4 class="font-semibold text-orange-800 mb-2">适用场景</h4>
                            <ul class="text-orange-700 space-y-2">
                                <li>需要处理复杂启动参数的初始化</li>
                                <li>依赖其他Bean完成的初始化</li>
                                <li>需要访问完整应用上下文的场景</li>
                            </ul>
                        </div>
                    </div>
                </section>

                <!-- CommandLineRunner Section -->
                <section>
                    <h2 id="commandlinerunner" class="heading-font text-3xl font-bold text-gray-800 mb-6">CommandLineRunner 接口</h2>
                    <div class="pl-2 border-l-4 border-purple-500 mb-6">
                        <p class="text-lg text-gray-700">它用于在Spring Boot应用启动后，执行一些特定的逻辑或任务，例如预加载数据、初始化资源、启动定时任务等。</p>
                    </div>
                    <div class="code-block p-4 rounded-lg mb-6 overflow-x-auto">
                        <pre class="text-sm"><code>import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyInitializer implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        // 项目启动成功后执行
        System.out.println("项目启动成功了，可以做一些初始化操作了");
    }
}</code></pre>
                    </div>
                    <div class="flex flex-col md:flex-row gap-6 mb-6">
                        <div class="flex-1 bg-purple-50 border border-purple-100 rounded-lg p-4">
                            <h4 class="font-semibold text-purple-800 mb-2 flex items-center">
                                <i class="fas fa-info-circle mr-2"></i>
                                工作原理
                            </h4>
                            <p class="text-purple-700">Spring Boot会自动检测所有实现了CommandLineRunner接口的Bean，并在应用启动过程的最后阶段调用它们的run方法。</p>
                        </div>
                        <div class="flex-1 bg-indigo-50 border border-indigo-100 rounded-lg p-4">
                            <h4 class="font-semibold text-indigo-800 mb-2 flex items-center">
                                <i class="fas fa-exclamation-triangle mr-2"></i>
                                注意事项
                            </h4>
                            <p class="text-indigo-700">如果有多个CommandLineRunner实现，可以使用@Order注解或实现Ordered接口来控制执行顺序。</p>
                        </div>
                    </div>
                </section>

                <!-- ApplicationListener Section -->
                <section>
                    <h2 id="applicationlistener" class="heading-font text-3xl font-bold text-gray-800 mb-6">ApplicationListener 接口</h2>
                    <div class="pl-2 border-l-4 border-yellow-500 mb-6">
                        <p class="text-lg text-gray-700">监听<code class="bg-yellow-50 text-yellow-700 px-2 py-1 rounded">ContextRefreshedEvent</code>事件，当Spring容器完成刷新时（所有Bean都被初始化并装载到容器中）触发。</p>
                    </div>
                    <div class="code-block p-4 rounded-lg mb-6 overflow-x-auto">
                        <pre class="text-sm"><code>import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@Component
public class MyInitializer implements ApplicationListener&lt;ContextRefreshedEvent&gt; {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 在Spring容器刷新完成后执行
        System.out.println("Spring容器已刷新完成，可以执行初始化逻辑...");
    }
}</code></pre>
                    </div>
                    <div class="bg-yellow-50 border border-yellow-100 rounded-lg p-4">
                        <div class="flex items-start">
                            <div class="flex-shrink-0 pt-1">
                                <i class="fas fa-question-circle text-yellow-600 text-xl mr-3"></i>
                            </div>
                            <div>
                                <h4 class="font-semibold text-yellow-800 mb-2">何时选择ApplicationListener？</h4>
                                <p class="text-yellow-700">当您需要精确控制初始化时机，或者在Spring上下文完全刷新后执行某些操作时，ApplicationListener是理想选择。它特别适用于需要确保所有Bean都已初始化完成的场景。</p>
                            </div>
                        </div>
                    </div>
                </section>
            </div>

            <!-- Comparison Section -->
            <section class="mt-16">
                <h2 class="heading-font text-3xl font-bold text-gray-800 mb-8 text-center">初始化方法对比指南</h2>
                <div class="overflow-x-auto">
                    <table class="min-w-full bg-white rounded-lg overflow-hidden">
                        <thead class="bg-gray-100">
                            <tr>
                                <th class="py-3 px-4 text-left font-semibold text-gray-700">方法</th>
                                <th class="py-3 px-4 text-left font-semibold text-gray-700">执行时机</th>
                                <th class="py-3 px-4 text-left font-semibold text-gray-700">参数访问</th>
                                <th class="py-3 px-4 text-left font-semibold text-gray-700">复杂度</th>
                                <th class="py-3 px-4 text-left font-semibold text-gray-700">推荐场景</th>
                            </tr>
                        </thead>
                        <tbody class="divide-y divide-gray-200">
                            <tr class="hover:bg-gray-50">
                                <td class="py-4 px-4 font-medium text-blue-600">@PostConstruct</td>
                                <td class="py-4 px-4 text-gray-600">Bean初始化后</td>
                                <td class="py-4 px-4 text-gray-600">无</td>
                                <td class="py-4 px-4 text-gray-600">低</td>
                                <td class="py-4 px-4 text-gray-600">简单的Bean初始化</td>
                            </tr>
                            <tr class="hover:bg-gray-50">
                                <td class="py-4 px-4 font-medium text-green-600">ApplicationRunner</td>
                                <td class="py-4 px-4 text-gray-600">应用启动后</td>
                                <td class="py-4 px-4 text-gray-600">ApplicationArguments</td>
                                <td class="py-4 px-4 text-gray-600">中</td>
                                <td class="py-4 px-4 text-gray-600">需要处理复杂启动参数</td>
                            </tr>
                            <tr class="hover:bg-gray-50">
                                <td class="py-4 px-4 font-medium text-purple-600">CommandLineRunner</td>
                                <td class="py-4 px-4 text-gray-600">应用启动后</td>
                                <td class="py-4 px-4 text-gray-600">String[] args</td>
                                <td class="py-4 px-4 text-gray-600">中</td>
                                <td class="py-4 px-4 text-gray-600">简单的启动任务</td>
                            </tr>
                            <tr class="hover:bg-gray-50">
                                <td class="py-4 px-4 font-medium text-yellow-600">ApplicationListener</td>
                                <td class="py-4 px-4 text-gray-600">上下文刷新后</td>
                                <td class="py-4 px-4 text-gray-600">ContextRefreshedEvent</td>
                                <td class="py-4 px-4 text-gray-600">高</td>
                                <td class="py-4 px-4 text-gray-600">精确控制初始化时机</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </section>

            <!-- Summary Section -->
            <section class="mt-16 bg-gray-50 rounded-xl p-8 border border-gray-200">
                <h2 class="heading-font text-3xl font-bold text-gray-800 mb-6">总结与选择建议</h2>
                <div class="grid md:grid-cols-2 gap-8">
                    <div>
                        <h3 class="text-xl font-semibold text-gray-700 mb-4 flex items-center">
                            <i class="fas fa-check-circle text-green-500 mr-3"></i>
                            如何选择初始化方法？
                        </h3>
                        <ul class="space-y-3 text-gray-600">
                            <li class="flex items-start">
                                <span class="bg-blue-100 text-blue-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full">简单</span>
                                <span>选择<code class="bg-blue-50 text-blue-700 px-1 py-0.5 rounded">@PostConstruct</code>进行Bean内部初始化</span>
                            </li>
                            <li class="flex items-start">
                                <span class="bg-green-100 text-green-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full">通用</span>
                                <span>选择<code class="bg-green-50 text-green-700 px-1 py-0.5 rounded">ApplicationRunner</code>处理复杂启动逻辑</span>
                            </li>
                            <li class="flex items-start">
                                <span class="bg-purple-100 text-purple-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full">直接</span>
                                <span>选择<code class="bg-purple-50 text-purple-700 px-1 py-0.5 rounded">CommandLineRunner</code>执行简单启动任务</span>
                            </li>
                            <li class="flex items-start">
                                <span class="bg-yellow-100 text-yellow-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full">精确</span>
                                <span>选择<code class="bg-yellow-50 text-yellow-700 px-1 py-0.5 rounded">ApplicationListener</code>控制精确执行时机</span>
                            </li>
                        </ul>
                    </div>
                    <div>
                        <h3 class="text-xl font-semibold text-gray-700 mb-4 flex items-center">
                            <i class="fas fa-lightbulb text-yellow-500 mr-3"></i>
                            通用建议
                        </h3>
                        <div class="space-y-3 text-gray-600">
                            <p>无论使用哪种方式，都可以在应用启动后执行一些初始化操作，例如初始化数据库、预热缓存、加载配置等。选择适合自己需求的方式来进行初始化操作即可。</p>
                            <p class="font-medium text-gray-700">关键考虑因素：</p>
                            <ul class="list-disc pl-5">
                                <li>初始化任务的复杂度</li>
                                <li>是否需要访问启动参数</li>
                                <li>执行时机的精确要求</li>
                                <li>与其他组件的依赖关系</li>
                            </ul>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-12 px-4">
        <div class="container mx-auto max-w-5xl">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-6 md:mb-0">
                    <h3 class="text-xl font-bold text-white mb-2">技术小馆</h3>
                    <p class="text-gray-400">专业的开发者知识分享平台</p>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="inline-flex items-center px-4 py-2 border border-gray-600 rounded-lg hover:bg-gray-800 hover:text-white transition-colors">
                        <i class="fas fa-external-link-alt mr-2"></i>
                        <span>访问语雀主页</span>
                    </a>
                </div>
            </div>
            <div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400 text-sm">
                <p>© 2023 技术小馆. 保留所有权利.</p>
            </div>
        </div>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // 如果有需要，可以在这里初始化mermaid图表
            mermaid.initialize({
                startOnLoad: true,
                theme: 'default',
                flowchart: {
                    useMaxWidth: true,
                    htmlLabels: true,
                    curve: 'basis'
                }
            });
            
            // 平滑滚动
            document.querySelectorAll('a[href^="#"]').forEach(anchor => {
                anchor.addEventListener('click', function (e) {
                    e.preventDefault();
                    document.querySelector(this.getAttribute('href')).scrollIntoView({
                        behavior: 'smooth'
                    });
                });
            });
        });
    </script>
</body>
</html>
```